package com.cy.pj.modules.service.impl;

import com.cy.pj.common.bo.PageObject;
import com.cy.pj.common.exception.ServiceException;
import com.cy.pj.common.utils.ShiroUtils;
import com.cy.pj.modules.entity.Sku;
import com.cy.pj.modules.entity.Spu;
import com.cy.pj.modules.mapper.SkuMapper;
import com.cy.pj.modules.mapper.SpuMapper;
import com.cy.pj.modules.service.ISkuService;
import com.cy.pj.modules.vo.SkuVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


/**
 * 商品货品Service业务层处理
 *
 * @author kiven
 * @date 2023-02-09
 */
@Service
public class SkuServiceImpl implements ISkuService {
    @Autowired
    private SkuMapper skuMapper;
    @Value("${fz.pageHelper.pageSize}")
    private Integer pageSize;

    @Value("${fz.manager}")
    private String manager;
    @Autowired
    private SpuMapper spuMapper;



    /**
     * 查询商品货品
     *
     * @param id 商品货品ID
     * @return 商品货品
     */
    @Override
    public Sku selectSkuById(Long id) {
        return skuMapper.selectSkuById(id);
    }

    /**
     * 查询商品货品列表
     *
     * @param sku 商品货品
     * @return 商品货品
     */
    @Override
    public PageObject<Sku> selectSkuList(Sku sku, Integer pageCurrent) {
        //1.参数校验
        if (pageCurrent == null || pageCurrent < 1) {
            throw new IllegalArgumentException("页码值无效");
        }
        //2.设置分页参数
        String orderBy = "id desc";
        Page<Sku> page = PageHelper.startPage(pageCurrent, pageSize, orderBy);
        //3.查询当前页记录
        List<Sku> list = skuMapper.selectSkuList(sku);
        return new PageObject<>(list, (int) page.getTotal(), page.getPages(), pageSize, pageCurrent);
    }

    /**
     * 新增商品货品
     *
     * @param sku 商品货品
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSku(Sku sku) {
        Sku sku1 = new Sku();
        sku1.setShopId(sku.getShopId());
        sku1.setSpuId(sku.getSpuId());
        sku1.setSpecifications(sku.getSpecifications());
        Sku skus = skuMapper.selectSkuByShopIdAndSpecificationsAndSpu(sku1);
        if (skus!=null) {
            throw new ServiceException("该品已经存在,请勿重复添加");
        }
        if ( !(ShiroUtils.getUser().getShopId().equals(sku.getShopId())||manager.equals(ShiroUtils.getUsername()))   ) {
            throw new ServiceException("不允许操作其他店铺信息");
        }
        if(sku.getNumber()<0){
            throw new ServiceException("数量不能小于0");
        }
        sku.setAddTime(new Date());
        sku.setCreateBy(ShiroUtils.getUsername());
        int i = skuMapper.insertSku(sku);
        // 插入时修改 spu总库存
        Spu spu = spuMapper.selectSpuById(sku.getSpuId());
        spu.setNum(spu.getNum() + sku.getNumber());
        spuMapper.updateSpu(spu);
        return i;
    }

    /**
     * 修改商品货品  其他业务要调用sku的库存修改,则需要调用本方法
     *
     * @param sku 商品货品
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSku(Sku sku) {
        if(sku.getNumber()<0){
            throw new ServiceException("数量不能小于0");
        }
        // 修改时修改 spu总库存
        sku.setUpdateBy(ShiroUtils.getUsername());
        sku.setUpdateTime(new Date());
        // 得到原sku库存  库存做修改需要加锁
        Sku oldSku = skuMapper.selectSkuByIdForUpdate(sku.getId());
        if (oldSku == null) {
            throw new ServiceException("该数据不存在");
        }
        //
        Long oldStock = oldSku.getNumber();
        // 如果库存数量没变,则不修改spu总库存
        if (oldStock.equals(sku.getNumber())) {
            return skuMapper.updateSku(sku);
        }
        int i = skuMapper.updateSku(sku);
        // 若库存不一致修改时修改 spu总库存需要加读锁
        Spu spu = null;
        if (sku.getSpuId()!=null&&sku.getSpuId()!=0) {
            spu = spuMapper.selectSpuByIdForUpdate(sku.getSpuId());
            if(spu==null){
                throw new ServiceException("该品不存在");
            }
        }else{
            spu = spuMapper.selectSpuByIdForUpdate(oldSku.getSpuId());
        }
        // 结果可能是负数,可能是正数 ,把差额加到spu里面即可
        Long difference =sku.getNumber()- oldStock ;
        spu.setNum(spu.getNum() + difference);
        spuMapper.updateSpu(spu);
        return i;

    }

    /**
     * 删除商品货品对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.REPEATABLE_READ)
    public int deleteSkuByIds(String ids) {
        String[] idsArray = ids.split(",");
        // 删除时修改 spu总库存
        if ( idsArray.length > 0) {
            for (String s : idsArray) {
                Sku sku = skuMapper.selectSkuById(Long.parseLong(s));
                if(sku!=null){
                    Spu spu = spuMapper.selectSpuById(sku.getSpuId());
                    Long num = spu.getNum();
                    Long number = sku.getNumber();
                    if (num > 0 && num > number) {
                        spu.setNum(num - number);
                        spuMapper.updateSpu(spu);
                    }
                }
            }
        }
        int i = skuMapper.deleteSkuByIds(idsArray);
        return i;
    }

    /**
     * 删除商品货品信息
     *
     * @param id 商品货品ID
     * @return 结果
     */
    @Override
    public int deleteSkuById(Long id) {
        return skuMapper.deleteSkuById(id);
    }

    @Override
    public SkuVo selectSkuAndSpuNameById(Long id) {
        SkuVo skuVo = skuMapper.selectSkuSpuNameById(id);
        if(skuVo==null){
            throw new ServiceException("该品不存在");
        }
        return skuVo;
    }

    @Override
    public String importDataSku(List<Sku> skuExcelList) {
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        Integer failureCount = 0;
        // 1.检查是否大于1000条
        if(skuExcelList.size()>1000){
            throw new ServiceException("导入数量不能大于1000条");
        }
        // 2.导入校验所有行列格式
        for (int i = 0; i < skuExcelList.size(); i++) {
            Sku sku = skuExcelList.get(i);
            if(StringUtils.isEmpty(sku.getSpecifications()) ||
                    sku.getSpuId()==null ||
                    sku.getNumber() == null||
                    StringUtils.isEmpty(sku.getPrice().toString())
            ){
                failureMsg.append("<br/> 第"+i+"条数据,请提供规格品类数量价格等数据");
                failureCount++;
                continue;
            }
            // 判断是否重复
            Sku sku1 = new Sku();
            sku1.setShopId(Long.parseLong(ShiroUtils.getUser().getShopId()));
            sku.setShopId(Long.parseLong(ShiroUtils.getUser().getShopId()));
            sku1.setSpuId(sku.getSpuId());
            sku1.setSpecifications(sku.getSpecifications());
            Sku skus = skuMapper.selectSkuByShopIdAndSpecificationsAndSpu(sku1);
            if (skus!=null) {
                failureMsg.append("<br/> 第"+i+"条数据,已存在相同的数据请勿重复导入");
                failureCount++;
                continue;
            }
            successMsg.append("<br/> 第"+i+"条数据,导入成功");
        }
        if(failureCount>0){
            failureMsg.insert(0, "很抱歉导入失败，请调整数据后重试,共"+failureCount+"条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }else{
            // 3.入库操作
            for (Sku sku : skuExcelList) {
                skuMapper.insertSku(sku);
            }
        }

        return successMsg.toString();
    }
}
